<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<div id="my_dataviz"></div>
<script>
    const svg = d3.select("#my_dataviz")
        .append("svg")
        .attr("width", 440)
        .attr("height", 440)
        .append("g")
        .attr("transform", "translate(220,220)")

    // create a matrix
    const matrix = [
        [0, 5871, 8916, 2868],
        [1951, 0, 2060, 6171],
        [8010, 16145, 0, 8045],
        [1013, 990, 940, 0]
    ];

    // 4 groups, so create a vector of 4 colors
    const colors = ["#440154ff", "#31668dff", "#37b578ff", "#fde725ff"]

    // give this matrix to d3.chord(): it will calculates all the info we need to draw arc and ribbon
    const res = d3.chord()
        .padAngle(0.05)
        .sortSubgroups(d3.descending)
        (matrix)

    // add the groups on the outer part of the circle
    svg
        .datum(res)
        .append("g")
        .selectAll("g")
        .data(function (d) {
            return d.groups;
        })
        .join("g")
        .append("path")
        .style("fill", (d, i) => colors[i])
        .style("stroke", "black")
        .attr("d", d3.arc()
            .innerRadius(200)
            .outerRadius(210)
        )

    // Add the links between groups
    svg
        .datum(res)
        .append("g")
        .selectAll("path")
        .data(d => d)
        .join("path")
        .attr("d", d3.ribbon()
            .radius(200)
        )
        .style("fill", d => colors[d.source.index]) // colors depend on the source group. Change to target otherwise.
        .style("stroke", "black");
</script>
</body>
</html>